package dkbta.util;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.StringWriter;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import dkbta.server.util.exceptions.IllegalQueryException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

/**
 * Holds useful methods
 * 
 * @author Uri Kanonov
 */
public class Utils{
	/**
	 * Returns true if the string is null or empty (length = 0)
	 * 
	 * @param s The string to be tested
	 * @return true if the string is null or empty (length = 0), false otherwise
	 */
	public static boolean isEmpty(String s){
		return s == null || s.isEmpty();
	}
	
	/**
     * Returns whether the given CharSequence contains only digits.
     */
    public static boolean isDigitsOnly(CharSequence str) {
        final int len = str.length();
        for (int i = 0; i < len; i++) {
            if (!Character.isDigit(str.charAt(i))) {
                return false;
            }
        }
        return true;
    }

	/**
	 * Parses an XML file as a DOM Document
	 * 
	 * @param xml The XML file
	 * @return DOM Document representation of the file
	 * @throws Exception If the file cannot be read
	 */
	public static Document readDOMDocFromXML(File xml) throws Exception{
		// Create a builder factory
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setValidating(false);

		// Create the builder and parse the file
		return factory.newDocumentBuilder().parse(xml);
	}

	/**
	 * Returns the enum constant of the specified enum type with the specified name. The
	 * name after trimming must be a case-insensitive match to an identifier used to
	 * declare an enum constant in this type.
	 * 
	 * @param enumType the <tt>Class</tt> object of the enum type from which to return a
	 *        constant
	 * @param name the name of the constant to return
	 * @return the enum constant of the specified enum type with the specified name
	 * @throws IllegalArgumentException If <tt>enumType</tt> or <tt>name</tt> is null.
	 *         Or if the specified enum type has no constant with the specified name, or
	 *         the specified class object does not represent an enum type
	 */
	public static <T extends Enum<T>> T enumForName(Class<T> enumType, String name){
		T result = null;
		if (enumType == null){
			throw new IllegalArgumentException("enumType cannot be null");
		}
		if (name != null && !(name = name.trim()).isEmpty()){
			try{
				result = Enum.valueOf(enumType, name.toUpperCase());
			}catch(IllegalArgumentException e){}
		}
		if (result == null){
			throw new IllegalArgumentException("'" + name + "' is not a valid "
					+ enumType.getName());
		}
		return result;
	}

	
	/**
	 * Parses a string as xml file and returns its root element
	 * @param xmlStr source String
	 * @return root Element represented by source String 
	 * @throws IllegalQueryException
	 */
	public static Element getDocument(String xmlStr) throws IllegalQueryException {
		// Create a builder factory
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setValidating(false);		
		ByteArrayInputStream stream = new ByteArrayInputStream(xmlStr.getBytes());		
		// Create the builder and parse the file
		try {
			return factory.newDocumentBuilder().parse(stream).getDocumentElement();
		} 
		catch (Exception e) {
			throw new IllegalQueryException();
		}
	}
	
	public static String xmlToString(Element root) throws TransformerFactoryConfigurationError, TransformerException{	
		Transformer transformer = TransformerFactory.newInstance().newTransformer();
		transformer.setOutputProperty(OutputKeys.INDENT, "yes");
		StreamResult result = new StreamResult(new StringWriter());
		DOMSource source = new DOMSource(root);
		transformer.transform(source, result);
		String xmlString = result.getWriter().toString();		
		return xmlString;
	}
	
	public static void writeXMLFile(Node root, String filename){
		try{
			Transformer tFormer = TransformerFactory.newInstance().newTransformer();
			tFormer.setOutputProperty(OutputKeys.INDENT, "yes");
			Source source = new DOMSource(root.getOwnerDocument());
			Result dest = new StreamResult(new File(filename));
			tFormer.transform(source,dest);
		}
		catch(Exception e){
			e.printStackTrace();
		}		
	}

      public static String now(String dateFormat) {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        return sdf.format(cal.getTime());
      }

}
